import pathToRegex from 'path-to-regexp'
import axios from 'axios'
import {MessageBox, Message} from 'element-ui'
import {getToken, removeToken} from "@/utils/auth"



const httpUtil = axios.create({
  timeout: 12000 // request timeout
})
httpUtil.interceptors.request.use(
  config => {
    const token = getToken();
    if (token) {
      config.headers['token'] = token
    }
    return config
  },
  error => {
    return Promise.reject(error)
  }
)

httpUtil.interceptors.response.use(
  response => {
    const res = response.data
    if (res.code && res.code !== 1) {
      if (res.code === 301 || res.code === 302 || res.code === 401) {
        MessageBox.confirm('登录状态失效，请退出重新登录', '确认退出', {
          confirmButtonText: '重新登录',
          cancelButtonText: '关闭',
          type: 'warning'
        }).then(() => {
          removeToken();
          location.reload()
        })
      }
      Message.error(res.msg)
      return Promise.reject(new Error(res.msg || 'Error'))
      // throw new Error(res.msg || 'Error')
    }
    return res;
  }, error => {
    Message.error(error.message)
    return Promise.reject(error)
  }
)
httpUtil.doRequest = function (url, method, params) {
  return httpUtil({
    url: url,
    method: method,
    params
  })
}
httpUtil.doGet = function (url, params) {
  return httpUtil({
    url: url,
    method: 'get',
    params
  })
}
httpUtil.doPost = function (headers, url, data) {
  return httpUtil({
    headers: headers,
    url: url,
    method: 'post',
    data: data
  })
}

// 编译过的url缓存
const pathToRegexCaches = {}

const hostRegex = /^(http|https):\/\/[\w.:]*\//

export function parseOptions(opts = {}) {
  const config = {...opts}
  let compileCache = pathToRegexCaches[config.url]
  const host = getHost(config.url || '')


  if (!compileCache) {
    // 先排除host段，因为host段的端口号与参数写法有冲突
    compileCache = pathToRegexCaches[config.url] =  pathToRegex.compile(config.url.replace(host, ''))
  }

  // 出去传输过来的url参数，并补回host段
  const url = host + compileCache(config.params)
  const method = (config.type || config.method || 'get').toLowerCase()
  const params = ['get', 'head', 'delete'].includes(method)
    ? Object.assign({}, config.data, config.query)
    : config.query
  return {
    ...config,
    params,
    url: url
  }
}

export function getHost(url) {
  const matches = url.match(hostRegex)
  if (matches) {
    return matches[0]
  }
  return ''
}

export default function (options = {}) {

  const config = parseOptions(options)
  return new Promise((resolve, reject) => {
      httpUtil(config).then(res => {
        if(res.code === 0) {
          if(res.data && res.data.data) {
            resolve(res.data.data)
          } else {
            resolve(res.data)
          }
        } else {
          resolve(res)
        }
      }).catch(e => {
        console.error(e)
        reject(e)
      })
  })
}
